package com.lzw.breezeNovel.webApp.service.impl.video;


import com.lzw.breezeNovel.common.exception.BaseException;
import com.lzw.breezeNovel.common.login.LoginUser;
import com.lzw.breezeNovel.common.login.LoginUserHolder;
import com.lzw.breezeNovel.common.result.ResultCodeEnum;
import com.lzw.breezeNovel.model.entity.pojo.user.UserInfo;
import com.lzw.breezeNovel.model.entity.pojo.video.ShortVideo;
import com.lzw.breezeNovel.model.entity.query.PaginationResultQuery;
import com.lzw.breezeNovel.model.entity.query.video.ShortVideoQuery;
import com.lzw.breezeNovel.webApp.mapper.user.UserLikeMapper;
import com.lzw.breezeNovel.webApp.mapper.video.*;
import com.lzw.breezeNovel.webApp.service.impl.common.AsyncService;
import com.lzw.breezeNovel.webApp.mapper.user.UserInfoMapper;
import com.lzw.breezeNovel.webApp.service.video.ShortVideoService;
import com.lzw.breezeNovel.webApp.vo.video.ShortVideoVo;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author 清风明月
 * @Package com.lzw.breezeNovel.webApp.service.impl.video
 * @date 2025/3/23
 * @description 短视频
 */
@Service
@SuppressWarnings("all")
public class ShortVideoServiceImpl implements ShortVideoService {

    /**
     * 注入mapper
     */
    @Autowired
    private ShortVideoMapper shortVideoMapper;
    /**
     * 注入用户mapper
     */
    @Autowired
    private UserInfoMapper userInfoMapper;
    /**
     * 注入redis
     */
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 注入异步服务
     */
    @Autowired
    private AsyncService asyncService;
    /**
     * 注入用户点赞表
     */
    @Autowired
    private UserLikeMapper userLikeMapper;

    /**
     * 注入视频点赞表
     */
    @Autowired
    private VideoLikeMapper  videoLikeMapper;




    /**
     * 添加短视频
     * @param shortVideoQuery
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addShortVideo(ShortVideoQuery shortVideoQuery) {
        //获取当前用户
        Long userId = getUserId();
        //创建短视频对象
        ShortVideo shortVideo = new ShortVideo();
        //进行对象拷贝
        BeanUtils.copyProperties(shortVideoQuery,shortVideo);
        //设置用户id
        shortVideo.setUserId(userId);
        //设置播放次数
        shortVideo.setPlayCount(0);
        //设置点赞次数
        shortVideo.setLikeCount(0);
        //设置上传时间
        shortVideo.setUploadTime(new Date());
        //设置视频的分享数量
        shortVideo.setShare(0);
        //进行插入
        shortVideoMapper.insert(shortVideo);
    }

    /**
     * 分页查询所有短视频
     * @param pageNo
     * @param size
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public PaginationResultQuery<ShortVideoVo> getAllShortVideo(Integer pageNo, Integer size) {
        //获取当前用户
        Long userId = getUserId();
        //计算分页
        Integer start = getStart(pageNo, size);
        //查询所有短视频
        List<ShortVideo> shortVideos = shortVideoMapper.getAllShortVideo(start, size, userId);
        //对对象进行拷贝
        List<ShortVideoVo> shortVideoVos = Copy(shortVideos);
        //分装分页对象
        PaginationResultQuery<ShortVideoVo> paginationResultQuery = new PaginationResultQuery<>(0, size, pageNo, shortVideos.size(), shortVideoVos);
        return paginationResultQuery;
    }

    /**
     * 更新分享次数
     * @param videoId
     * @param userId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateShareCount(Long videoId, Long userId) {
        // 参数校验
        if (videoId == null || userId == null) {
            throw new IllegalArgumentException("参数不能为空");
        }

        // Redis的键
        String shareCountKey = "video:share:" + videoId;

        // 使用Redis原子操作增加分享次数
        redisTemplate.opsForValue().increment(shareCountKey, 1);

        // 异步更新数据库
        asyncService.updateShareCountAsync(videoId);
    }

    /**
     * 更新播放次数
     * 使用redis缓存进行优化更新排放量
     * @param videoId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePlayCount(Long videoId) {
        //创建redis的键
        String playCountKey = "video:play:" + videoId;
        //使用redis的原子操作进行增加
        redisTemplate.opsForValue().increment(playCountKey, 1);
        //定期将数据更新到数据库中
        syncPlayCountToDatabase(videoId);
    }

    /**
     * 根据用户id查询所有短视频
     * @param pageNo
     * @param size
     * @return
     */
    @Override
    public PaginationResultQuery<ShortVideoVo> getAllVideoByUserId(Integer pageNo, Integer size) {
        //获取当前用户
        Long userId = getUserId();
        //计算分页
        Integer start = getStart(pageNo, size);
        //查询所有短视频
        List<ShortVideo> shortVideos = shortVideoMapper.getAllVideoByUserId(start, size, userId);
        //对对象进行拷贝
        List<ShortVideoVo> shortVideoVos = Copy(shortVideos);
        //分装分页对象
        PaginationResultQuery<ShortVideoVo> paginationResultQuery = new PaginationResultQuery<>(0, size, pageNo, shortVideos.size(), shortVideoVos);
        return paginationResultQuery;
    }

    /**
     * 删除短视频
     * @param videoId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteShortVideo(Long videoId) {
        //获取当前用户
        Long userId = getUserId();
        //异步更新或者短视频点赞数量
        asyncService.updateVideoLikeCountAsync(videoId,userId);
        //删除短视频
        shortVideoMapper.deleteShortVideo(videoId, userId);
    }


    /**
     * 同步播放次数到数据库
     * @param videoId
     */
    private void syncPlayCountToDatabase(Long videoId) {
        //redis的key
        String playCountKey = "video:play:" + videoId;
        //获取redis中的播放次数
        Integer count = (Integer)redisTemplate.opsForValue().get(playCountKey);
        //判断是否存在
        if(count != null && count > 0)
        {
            //更新数据库
            shortVideoMapper.updatePlayCount(videoId, count);
            //清空redis
            redisTemplate.delete(playCountKey);
        }
    }


    /**
     * 拷贝对象
     */
    @Nullable
    @Contract(pure = true)
    private List<ShortVideoVo> Copy(List<ShortVideo> shortVideos) {
        //判断是否为空
        if(shortVideos == null || shortVideos.size() == 0)
        {
            return null;
        }
        return shortVideos.stream()
                .map(shortVideo -> {
                    //创建对象
                    ShortVideoVo shortVideoVo = new ShortVideoVo();
                    //进行对象拷贝
                    BeanUtils.copyProperties(shortVideo,shortVideoVo);
                    return shortVideoVo;
                }).collect(Collectors.toList());
    }

    /**
     * 计算分页
     * @return
     */
    @NotNull
    private Integer getStart(Integer pageNo, Integer size) {
        //对分页进行判断
        pageNo = Optional.ofNullable(pageNo).orElse(1);
        size = Optional.ofNullable(size).orElse(10);
        pageNo = Math.max(pageNo, 1);
        size = Math.max(size, 1);
        return (pageNo - 1) * size;
    }

    /**
     * 获取用户id
     * @return
     */
    private Long getUserId() {
        //获取用户信息
        LoginUser loginUser = LoginUserHolder.getLoginUser();
        //判断用户是否登录
        if(loginUser == null)
        {
            throw new BaseException(ResultCodeEnum.APP_LOGIN_AUTH);
        }
        //获取用户手机号
        String phone = loginUser.getPhone();
        //根据手机号查询用户id
        UserInfo userInfo = userInfoMapper.selectByPhone(phone);
        return userInfo.getUserId();
    }
}
